* If the popup was previously now showing, it will be showed,
* otherwise it will change position according to @layout.
*
- * After calling this function, the result of the layout can be queried
- * using gdk_popup_get_position_x(), gdk_popup_get_position_y(),
- * gdk_surface_get_width(), gdk_surface_get_height(),
- * gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor().
+ * After calling this function, the result should be handled in response
+ * to the GdkSurface::layout signal being emitted. The resulting popup
+ * position can be queried using gdk_popup_get_position_x(),
+ * gdk_popup_get_position_y(), and the resulting size will be sent as
+ * parameters in the layout signal. Use gdk_popup_get_rect_anchor() and
+ * gdk_popup_get_surface_anchor() to get the resulting anchors.
*
* Presenting may have fail, for example if it was immediately
- * hidden if the @popup was set to autohide.
+ * hidden if the @popup was set to autohide. If presenting failed,
+ * GdkSurface::layout will not me emitted.
*
* Returns: %FALSE if it failed to be presented, otherwise %TRUE.
*/
* Gets the current popup surface anchor.
*
* The value returned may change after calling gdk_popup_present(),
- * or after the "popup-layout-changed" is emitted.
+ * or after the "GdkSurface::layout" signal is emitted.
*
* Returns: the current surface anchor value of @popup
*/
* Gets the current popup rectangle anchor.
*
* The value returned may change after calling gdk_popup_present(),
- * or after the "popup-layout-changed" is emitted.
+ * or after the "GdkSurface::layout" signal is emitted.
*
* Returns: the current rectangle anchor value of @popup
*/
gboolean should_constrain;
gboolean size_is_fixed;
} toplevel;
+ struct {
+ int x;
+ int y;
+ } popup;
int configured_width;
int configured_height;
gboolean surface_geometry_dirty;
impl->next_layout.popup.y,
impl->next_layout.configured_width,
impl->next_layout.configured_height);
- g_signal_emit_by_name (surface, "popup-layout");
}
static void
if (impl->next_layout.surface_geometry_dirty)
{
- g_warn_if_fail (GDK_IS_TOPLEVEL (impl));
- configure_toplevel_geometry (surface);
+ if (GDK_IS_TOPLEVEL (impl))
+ configure_toplevel_geometry (surface);
+ else if (GDK_IS_POPUP (impl))
+ configure_popup_geometry (surface);
impl->next_layout.surface_geometry_dirty = FALSE;
}
width = impl->pending.popup.width;
height = impl->pending.popup.height;
- gdk_wayland_surface_resize (surface, width, height, impl->scale);
+ x += surface->parent->shadow_left;
+ y += surface->parent->shadow_top;
update_popup_layout_state (surface,
x, y,
width, height,
impl->popup.layout);
- if (!impl->pending.popup.has_repositioned_token &&
- !impl->pending.is_initial_configure)
- g_signal_emit_by_name (surface, "popup-layout-changed");
-
- gdk_surface_invalidate_rect (surface, NULL);
+ impl->next_layout.popup.x = x;
+ impl->next_layout.popup.y = y;
+ impl->next_layout.configured_width = width;
+ impl->next_layout.configured_height = height;
+ impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
}
static void
int height,
GdkPopupLayout *layout)
{
- int surface_x, surface_y;
- int surface_width, surface_height;
GdkRectangle best_rect;
GdkRectangle flipped_rect;
GdkGravity rect_anchor;
GdkGravity surface_anchor;
GdkAnchorHints anchor_hints;
- x += surface->parent->shadow_left;
- y += surface->parent->shadow_top;
-
- surface_x = x;
- surface_y = y;
- surface_width = width + surface->shadow_left + surface->shadow_right;
- surface_height = height + surface->shadow_top + surface->shadow_bottom;
-
- gdk_wayland_surface_move_resize (surface,
- surface_x, surface_y,
- surface_width, surface_height);
-
rect_anchor = gdk_popup_layout_get_rect_anchor (layout);
surface_anchor = gdk_popup_layout_get_surface_anchor (layout);
anchor_hints = gdk_popup_layout_get_anchor_hints (layout);
g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
}
- gtk_widget_allocate (GTK_WIDGET (popover),
- gdk_surface_get_width (priv->surface),
- gdk_surface_get_height (priv->surface),
- -1, NULL);
-
gtk_widget_queue_draw (GTK_WIDGET (popover));
}
update_popover_layout (popover, gdk_popup_layout_ref (priv->layout));
}
+static void
+surface_layout (GdkSurface *surface,
+ int width,
+ int height,
+ GtkWidget *widget)
+{
+ GtkPopover *popover = GTK_POPOVER (widget);
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+ update_popover_layout (popover, gdk_popup_layout_ref (priv->layout));
+ if (_gtk_widget_get_alloc_needed (widget))
+ gtk_widget_allocate (widget, width, height, -1, NULL);
+}
+
static void
gtk_popover_activate_default (GtkPopover *popover)
{
g_signal_connect (priv->surface, "render", G_CALLBACK (surface_render), widget);
g_signal_connect (priv->surface, "event", G_CALLBACK (surface_event), widget);
g_signal_connect (priv->surface, "popup-layout-changed", G_CALLBACK (popup_layout_changed), widget);
+ g_signal_connect (priv->surface, "layout", G_CALLBACK (surface_layout), widget);
GTK_WIDGET_CLASS (gtk_popover_parent_class)->realize (widget);
g_signal_handlers_disconnect_by_func (priv->surface, surface_render, widget);
g_signal_handlers_disconnect_by_func (priv->surface, surface_event, widget);
g_signal_handlers_disconnect_by_func (priv->surface, popup_layout_changed, widget);
+ g_signal_handlers_disconnect_by_func (priv->surface, surface_layout, widget);
gdk_surface_set_widget (priv->surface, NULL);
gdk_surface_destroy (priv->surface);
g_clear_object (&priv->surface);